package com.itheima.service.impl;

import com.itheima.common.vo.ReportVo;
import com.itheima.common.vo.SetmealVo;
import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.ReportMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.pojo.OrderVo;
import com.itheima.pojo.Setmeal;
import com.itheima.service.ReportService;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private MemberMapper memberMapper;

    /**
     * 获取会员数量统计数据
     *
     * @return
     */
    public ReportVo getMemberReport() {

        List<Integer> memberCount = new ArrayList<>();
        List<String> months = new ArrayList<>();

        //获取Member表中所有数据的reg_time字段
        List<Date> regTimes = reportMapper.getRegTime();

        if (regTimes != null && !regTimes.isEmpty()) {
            //对regTimes进行遍历，过滤掉同一年同一月份的数据
            for (int i = 0; i < regTimes.size(); i++) {
                Date regTime = regTimes.get(i);
                String yearMonth = getYearMonth(regTime);
                for (int j = i + 1; j < regTimes.size(); j++) {
                    Date nextRegTime = regTimes.get(j);
                    String nextYearMonth = getYearMonth(nextRegTime);
                    if (yearMonth.equals(nextYearMonth)) {
                        regTimes.remove(j);
                        j--;
                    }
                }
            }

            for (Date regTime : regTimes) {
                Date firstDay = getFirstDay(regTime);
                Date lastDay = getLastDay(regTime);

                // 获取会员数量
                memberCount.add(reportMapper.getMemberCount(firstDay, lastDay));

                // 获取月份
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
                months.add(sdf.format(lastDay));
            }
        }

        return new ReportVo(months, memberCount, null, null);
    }

    /**
     * 获取指定日期的最后一天
     *
     * @param date
     * @return
     */
    private Date getLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int lastDay = calendar.getActualMaximum(Calendar.DATE);
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        return calendar.getTime();
    }

    /**
     * 获取指定日期的第一天
     */
    private Date getFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int firstDay = calendar.getActualMinimum(Calendar.DATE);
        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
        return calendar.getTime();
    }

    /**
     * 获取指定日期的年月
     */
    private String getYearMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        return year + "-" + month;
    }

    /**
     * 获取套餐数量统计数据
     */
    public ReportVo getSetmealReport() {
        List<String> setmealNames = new ArrayList<>();

        List<SetmealVo> setmealCount = reportMapper.getSetmealCount();

        if (setmealCount != null && !setmealCount.isEmpty()) {
            for (SetmealVo setmealVo : setmealCount) {
                setmealNames.add(setmealVo.getName());
            }
        }

        return new ReportVo(null, null, setmealNames, setmealCount);
    }

    /**
     * 获取运营数据
     */
    public ReportVo getBusinessReportData() {

        ReportVo reportVo = new ReportVo();

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        reportVo.setReportDate(sdf.format(date));

        Date firstDayOfWeek = getFirstDayOfWeek(date);

        reportVo.setThisWeekNewMember(memberMapper.getNewMember(firstDayOfWeek, date));

        OrderVo orderVo = orderMapper.getOrderAndVisitsNumber(firstDayOfWeek, date);
        if (orderVo != null && orderVo.getOrderNumber() != null && orderVo.getVisitsNumber() != null) {
            reportVo.setThisWeekOrderNumber(orderVo.getOrderNumber());
            reportVo.setThisWeekVisitsNumber(orderVo.getVisitsNumber());
        }

        reportVo.setThisMonthNewMember(memberMapper.getNewMember(getFirstDay(date), getLastDay(date)));

        orderVo = orderMapper.getOrderAndVisitsNumber(getFirstDay(date), getLastDay(date));
        if (orderVo != null && orderVo.getOrderNumber() != null && orderVo.getVisitsNumber() != null) {
            reportVo.setThisMonthOrderNumber(orderVo.getOrderNumber());
            reportVo.setThisMonthVisitsNumber(orderVo.getVisitsNumber());
        }

        reportVo.setTotalMember(memberMapper.getTotalMember());

        reportVo.setTodayNewMember(memberMapper.getTotalNewMember(date));

        orderVo = orderMapper.getTotalOrderAndVisitsNumber(date);
        if (orderVo != null && orderVo.getOrderNumber() != null && orderVo.getVisitsNumber() != null) {
            reportVo.setTodayOrderNumber(orderVo.getOrderNumber());
            reportVo.setTodayVisitsNumber(orderVo.getVisitsNumber());
        }

        Integer orderTotal = orderMapper.getTotal();
        List<SetmealVo> setmealVoList = reportMapper.getSetmealCount();
        if (setmealVoList != null && !setmealVoList.isEmpty()) {
            setmealVoList.forEach(setmealVo -> {
                setmealVo.setSetmeal_count(setmealVo.getValue());
                setmealVo.setProportion(setmealVo.getValue() / orderTotal.doubleValue());
            });
        }

        reportVo.setHotSetmeal(setmealVoList);

        return reportVo;
    }

    /**
     * 获取当前日期一周内的最小时间
     */
    private Date getFirstDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.add(Calendar.DATE, -6);
        return c.getTime();
    }

    /**
     * 导出运营数据报表
     */
    public void exportBusinessReport(HttpServletResponse response) {

        ReportVo reportVo = getBusinessReportData();

        try {
            XSSFWorkbook excel = new XSSFWorkbook(this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx"));
            XSSFSheet sheet = excel.getSheetAt(0);

            if (reportVo != null) {
                if (reportVo.getReportDate() != null) {
                    sheet.getRow(2).getCell(5).setCellValue(reportVo.getReportDate());
                } else {
                    sheet.getRow(2).getCell(5).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                }
                if (reportVo.getTodayNewMember() != null) {
                    sheet.getRow(4).getCell(5).setCellValue(reportVo.getTodayNewMember());
                } else {
                    sheet.getRow(4).getCell(5).setCellValue(0);
                }
                if (reportVo.getTotalMember() != null) {
                    sheet.getRow(4).getCell(7).setCellValue(reportVo.getTotalMember());
                } else {
                    sheet.getRow(4).getCell(7).setCellValue(0);
                }
                if (reportVo.getThisWeekNewMember() != null) {
                    sheet.getRow(5).getCell(5).setCellValue(reportVo.getThisWeekNewMember());
                } else {
                    sheet.getRow(5).getCell(5).setCellValue(0);
                }
                if (reportVo.getThisMonthNewMember() != null) {
                    sheet.getRow(5).getCell(7).setCellValue(reportVo.getThisMonthNewMember());
                } else {
                    sheet.getRow(5).getCell(7).setCellValue(0);
                }
                if (reportVo.getTodayOrderNumber() != null) {
                    sheet.getRow(7).getCell(5).setCellValue(reportVo.getTodayOrderNumber());
                } else {
                    sheet.getRow(7).getCell(5).setCellValue(0);
                }
                if (reportVo.getTodayVisitsNumber() != null) {
                    sheet.getRow(7).getCell(7).setCellValue(reportVo.getTodayVisitsNumber());
                } else {
                    sheet.getRow(7).getCell(7).setCellValue(0);
                }
                if (reportVo.getThisWeekOrderNumber() != null) {
                    sheet.getRow(8).getCell(5).setCellValue(reportVo.getThisWeekOrderNumber());
                } else {
                    sheet.getRow(8).getCell(5).setCellValue(0);
                }
                if (reportVo.getThisWeekVisitsNumber() != null) {
                    sheet.getRow(8).getCell(7).setCellValue(reportVo.getThisWeekVisitsNumber());
                } else {
                    sheet.getRow(8).getCell(7).setCellValue(0);
                }
                if (reportVo.getThisMonthOrderNumber() != null) {
                    sheet.getRow(9).getCell(5).setCellValue(reportVo.getThisMonthOrderNumber());
                } else {
                    sheet.getRow(9).getCell(5).setCellValue(0);
                }
                if (reportVo.getThisMonthVisitsNumber() != null) {
                    sheet.getRow(9).getCell(7).setCellValue(reportVo.getThisMonthVisitsNumber());
                } else {
                    sheet.getRow(9).getCell(7).setCellValue(0);
                }

                if (reportVo.getHotSetmeal() != null && !reportVo.getHotSetmeal().isEmpty()) {
                    for (int i = 0, len = reportVo.getHotSetmeal().size(); i < len; i++) {
                        XSSFRow row = sheet.getRow(12 + i);
                        SetmealVo setmealVo = reportVo.getHotSetmeal().get(i);
                        if (setmealVo != null) {
                            if (setmealVo.getName() != null) {
                                row.getCell(4).setCellValue(setmealVo.getName());
                            } else {
                                row.getCell(4).setCellValue("");
                            }
                            if (setmealVo.getSetmeal_count() != null) {
                                row.getCell(5).setCellValue(setmealVo.getSetmeal_count());
                            } else {
                                row.getCell(5).setCellValue(0);
                            }
                            if (setmealVo.getProportion() != null) {
                                row.getCell(6).setCellValue(setmealVo.getProportion());
                            } else {
                                row.getCell(6).setCellValue(0);
                            }
                        }
                    }
                }
            }

            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=report.xlsx");

            excel.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
